package infoexract.exractreason.samesent.treepattern.pattern;

import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;

public class SynTaxTreePattern {
	private SubTreePatternElement entityElements=null;
	private SubTreePatternElement attributeElements=null;
	private SubTreePatternElement rootElement;
	public void ReadPatternLine(String line)
	{
		String[] parts = line.split("#");
		if(!line.contains("##"))
		{
			this.entityElements = this.parseElementString(parts[0]+" "+parts[1]);
			if(parts.length>=3) this.attributeElements = this.parseElementString(parts[0]+" "+parts[2]);
		}
		else this.attributeElements = this.parseElementString(parts[0]+" "+parts[1]);
		
		this.rootElement = new SubTreePatternElement(parts[0],"NM");
	}
	
	public boolean isMatch(Node[] entityNodeParents, int entitySameIndex, Node[] attributeNodeParents, int attributeSameIndex)
	{
		boolean ismatch=false;
		ismatch = this.rootElement.isMatch(entityNodeParents[entitySameIndex]);
		if(ismatch==false) return ismatch;
		ismatch=this.isMatchElementsSequence(entityNodeParents, entitySameIndex, this.entityElements);
		if(ismatch==false) return ismatch;
		ismatch=this.isMatchElementsSequence(attributeNodeParents, attributeSameIndex, this.attributeElements);
		return ismatch;
	}
	
	private SubTreePatternElement parseElementString(String str)
	{
		String[] parts = str.split("\\s+");
		SubTreePatternElement startElement = new SubTreePatternElement();
		SubTreePatternElement currentElement = startElement;
		startElement.setElement(parts[0], "NM");
		currentElement = new SubTreePatternElement();
		startElement.setNext(currentElement);
		for(int i=1;i<parts.length;i++)
		{
			boolean isPositive = true;
			if(parts[i].startsWith("!")) 
			{
				isPositive = false;
				parts[i] = parts[i].substring(1);
			}
			int pos = parts[i].indexOf(':');
			String cat;
			String token;
			if(pos>0)
			{
				cat = parts[i].substring(0, pos);
				token = parts[i].substring(pos+1);
			}else
			{
				cat = parts[i].toUpperCase();
				token = "NM";
			}
			if(isPositive==false)
			{
				SubTreePatternElement tabuElement = new SubTreePatternElement(cat,token);
				currentElement.addTabuElement(tabuElement);
			}else
			{
				SubTreePatternElement nextElement = new SubTreePatternElement();
				currentElement.setNext(nextElement);
				currentElement.setElement(cat, token);
				currentElement = nextElement;
				
				
			}
		}
		return startElement;
	}
	private boolean isMatchElementsSequence(Node[] nodes,int sameIndex,SubTreePatternElement elements)
	{
		if(elements==null) return true;
		SubTreePatternElement currentElement = elements;
		for(int i=sameIndex;i>=0;i--)
		{
			Node currentNode = nodes[i];
			boolean isTabu = currentElement.isTabu(currentNode);
			if(isTabu==true) return false;
			boolean ismatch = currentElement.isMatch(currentNode);
			if(ismatch==true)
			{
				currentElement = currentElement.getNext();
			}
		}
		if(currentElement.getNext()==null) return true;
		else return false;
	}
	/*private boolean isMatchElementsSequence(Node[] nodes,int sameIndex,SubTreePatternElement elements)
	{
		if(elements==null) return true;
		SubTreePatternElement currentElement = elements;
		for(int i=sameIndex;i>=0;i--)
		{
			Node currentNode = nodes[i];
			boolean isTabu = currentElement.isTabu(currentNode);
			if(isTabu==true) return false;
			
			String cat = this.getNodeCat(currentNode);
			if(!this.isPartternElement(cat)) continue;
			
			if(currentElement.getNext()==null) return false;
			boolean ismatch = currentElement.isMatch(currentNode);
			
			if(ismatch==true)
			{
				currentElement = currentElement.getNext();
			}else return false;
		}
		if(currentElement.getNext()==null) return true;
		else return false;
	}*/
	private boolean isPartternElement(String cat)
	{
		if(cat.endsWith("P")) return true;
		if(cat.equals("NX")) return true;
		return false;
	}
	private String getNodeCat(Node node)
	{
		NamedNodeMap attributeMap = node.getAttributes();
		
		Node idAttribute = attributeMap.getNamedItem("cat");
		if(idAttribute==null) return "";
		return idAttribute.getNodeValue();
	}
}
